package com.wemei.auto.ui.tool.image.select.service.impl

import android.content.Context
import androidx.core.content.ContextCompat
import androidx.lifecycle.Observer
import com.alibaba.fastjson.JSON
import com.luck.picture.lib.basic.PictureSelector
import com.luck.picture.lib.config.SelectModeConfig
import com.luck.picture.lib.entity.LocalMedia
import com.luck.picture.lib.interfaces.OnResultCallbackListener
import com.luck.picture.lib.style.BottomNavBarStyle
import com.luck.picture.lib.style.PictureSelectorStyle
import com.luck.picture.lib.style.SelectMainStyle
import com.luck.picture.lib.style.TitleBarStyle
import com.luck.picture.lib.utils.DensityUtil
import com.wemei.auto.api.core.ApiComplete
import com.wemei.auto.api.core.ApiError
import com.wemei.auto.api.core.ApiProcess
import com.wemei.auto.api.core.FirmException
import com.wemei.auto.ui.AppCore
import com.wemei.auto.ui.R
import com.wemei.auto.ui.api.ApiObserver
import com.wemei.auto.ui.ext.DefaultLifecycleObserver
import com.wemei.auto.ui.helper.mohsi.MoshiUtils
import com.wemei.auto.ui.tool.image.select.domain.ImageSelectBean
import com.wemei.auto.ui.tool.image.select.engine.ExoPlayerEngine
import com.wemei.auto.ui.tool.image.select.engine.GlideEngine
import com.wemei.auto.ui.tool.image.select.service.IImageSelect
import com.wemei.auto.ui.tool.image.select.service.ImageSelectIntercept
import com.wemei.auto.ui.tool.image.select.service.ImageUploadUBuilder
import com.wemei.auto.ui.tool.image.select.service.intercept.QiNiuIntercept
import com.wemei.auto.ui.utils.Logger
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.suspendCancellableCoroutine
import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException

abstract class AbstractImageSelect : IImageSelect, DefaultLifecycleObserver {
    //    imageSelectIntercepts: (MutableList<ImageSelectIntercept>.() -> Unit)? = null
    private lateinit var mBuilder: ImageUploadUBuilder
    private var mImageSelectIntercepts: MutableList<ImageSelectIntercept>? = null
    abstract val context: Context?
    abstract val pictureSelector: PictureSelector
    private val selectorStyle = PictureSelectorStyle()

    init {
        // 主体风格
        val numberSelectMainStyle = SelectMainStyle()
        numberSelectMainStyle.isSelectNumberStyle = true
        numberSelectMainStyle.isPreviewSelectNumberStyle = false
        numberSelectMainStyle.isPreviewDisplaySelectGallery = true
        numberSelectMainStyle.selectBackground = R.drawable.ps_default_num_selector
        numberSelectMainStyle.previewSelectBackground = R.drawable.ps_preview_checkbox_selector
        numberSelectMainStyle.selectNormalBackgroundResources = R.drawable.ps_select_complete_normal_bg
        numberSelectMainStyle.selectNormalTextColor = ContextCompat.getColor(AppCore.app, R.color.ps_color_53575e)
        numberSelectMainStyle.setSelectNormalText(R.string.ps_send)
        numberSelectMainStyle.adapterPreviewGalleryBackgroundResource = R.drawable.ps_preview_gallery_bg
        numberSelectMainStyle.adapterPreviewGalleryItemSize = DensityUtil.dip2px(AppCore.app, 52f)
        numberSelectMainStyle.setPreviewSelectText(R.string.ps_select)
        numberSelectMainStyle.previewSelectTextSize = 14
        numberSelectMainStyle.previewSelectTextColor = ContextCompat.getColor(AppCore.app, R.color.ps_color_white)
        numberSelectMainStyle.previewSelectMarginRight = DensityUtil.dip2px(AppCore.app, 6f)
        numberSelectMainStyle.selectBackgroundResources = R.drawable.ps_select_complete_bg
        numberSelectMainStyle.setSelectText(R.string.ps_send_num)
        numberSelectMainStyle.selectTextColor = ContextCompat.getColor(AppCore.app, R.color.ps_color_white)
        numberSelectMainStyle.mainListBackgroundColor = ContextCompat.getColor(AppCore.app, R.color.ps_color_black)
        numberSelectMainStyle.isCompleteSelectRelativeTop = true
        numberSelectMainStyle.isPreviewSelectRelativeBottom = true
        numberSelectMainStyle.isAdapterItemIncludeEdge = false
        // 头部TitleBar 风格
        val numberTitleBarStyle = TitleBarStyle()
        numberTitleBarStyle.isHideCancelButton = true
        numberTitleBarStyle.isAlbumTitleRelativeLeft = true
        numberTitleBarStyle.titleAlbumBackgroundResource = R.drawable.ps_album_bg
        numberTitleBarStyle.titleDrawableRightResource = R.mipmap.ps_ic_grey_arrow
        numberTitleBarStyle.previewTitleLeftBackResource = R.mipmap.ps_ic_normal_back
        // 底部NavBar 风格
        val numberBottomNavBarStyle = BottomNavBarStyle()
        numberBottomNavBarStyle.bottomPreviewNarBarBackgroundColor = ContextCompat.getColor(AppCore.app, R.color.ps_color_half_grey)
        numberBottomNavBarStyle.setBottomPreviewNormalText(R.string.ps_preview)
        numberBottomNavBarStyle.bottomPreviewNormalTextColor = ContextCompat.getColor(AppCore.app, R.color.ps_color_9b)
        numberBottomNavBarStyle.bottomPreviewNormalTextSize = 16
        numberBottomNavBarStyle.isCompleteCountTips = false
        numberBottomNavBarStyle.setBottomPreviewSelectText(R.string.ps_preview_num)
        numberBottomNavBarStyle.bottomPreviewSelectTextColor = ContextCompat.getColor(AppCore.app, R.color.ps_color_white)

        selectorStyle.titleBarStyle = numberTitleBarStyle
        selectorStyle.bottomBarStyle = numberBottomNavBarStyle
        selectorStyle.selectMainStyle = numberSelectMainStyle
    }

    abstract fun <T> launchUI(
        block: suspend CoroutineScope.() -> T,
        apiObserver: Observer<ApiProcess<T>>? = null,
        error: ApiError? = null,
        complete: ApiComplete? = null,
    )

    init {
        mImageSelectIntercepts = mutableListOf<ImageSelectIntercept>().apply {
            QiNiuIntercept()
        }
    }

    override fun selectImage(config: (ImageUploadUBuilder.() -> Unit)?) {
        mBuilder = config?.let { ImageUploadUBuilder().apply(it) } ?: ImageUploadUBuilder()
        launchUI({
            var result = openGallery()
            mImageSelectIntercepts?.takeIf { it.isNotEmpty() }?.forEach {
                result = it.intercept(result)
            }
            result?.forEach {
                Logger.e("result==>" + it::class.java.name)
            }
            result
        }, ApiObserver(context) { result ->
            mBuilder.onUploadSuccessListener?.invoke(result)
        }, error = {
            mBuilder.onCancelSuccessListener?.invoke()
        })
    }

    private suspend fun openGallery() =
        suspendCancellableCoroutine<MutableList<ImageSelectBean>?> { coroutine ->
            pictureSelector
                .openGallery(mBuilder.selectMimeType)
                .setImageEngine(GlideEngine.createGlideEngine())
                .setSelectorUIStyle(selectorStyle)
                //.setCompressEngine(ImageCompressEngine.imageCompressEngine)
                // .setSandboxFileEngine(MeSandboxFileEngine.meSandboxFileEngine)
//                .setQueryOnlyMimeType("image/png", "image/jpeg", "image/jpg")
                .setMaxSelectNum(mBuilder.selectCount)
                .setImageSpanCount(mBuilder.columnCount)
                .isDisplayCamera(true)
                .isPreviewImage(true)
                .setSelectionMode(if (mBuilder.isMultipleChoice) SelectModeConfig.MULTIPLE else SelectModeConfig.SINGLE)
                .apply {
                    mBuilder.pictureConfig?.let { this.apply(it) }
                }
                .forResult(object : OnResultCallbackListener<LocalMedia> {
                    override fun onResult(result: ArrayList<LocalMedia>?) {
                        coroutine.resume(result?.mapTo(mutableListOf()) {
                            JSON.parseObject(MoshiUtils.toJSONString(it), ImageSelectBean::class.java)
                        })
                    }

                    override fun onCancel() {
                        coroutine.resumeWithException(FirmException("", -1, null))
                    }
                })
        }

    override fun preview(position: Int, list: MutableList<ImageSelectBean>) {
        val selectorStyle = PictureSelectorStyle()
        selectorStyle.titleBarStyle = TitleBarStyle().apply {
            isHideTitleBar = true
        }
        pictureSelector
            .openPreview()
            .setImageEngine(GlideEngine.createGlideEngine())
//            .isUseSystemVideoPlayer(true)
//            .setVideoPlayerEngine()
//            .isPreviewFullScreenMode(false)
            .setVideoPlayerEngine(ExoPlayerEngine(AppCore.app))
            .isAutoVideoPlay(true)
            .setSelectorUIStyle(selectorStyle)
            .startActivityPreview(position, false, ArrayList(list))
    }
}